package com.carey.blog.framework.latke.action.util;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.json.JSONObject;


import com.carey.blog.framework.latke.Latkes;
import com.carey.blog.framework.latke.RunsOnEnv;
import com.carey.blog.framework.latke.cache.Cache;
import com.carey.blog.framework.latke.cache.CacheFactory;
import com.carey.blog.framework.latke.util.freemarker.Templates;

/**
 * Page cache.
 * 
 * <p>
 * <b>Note</b>: The method <a
 * href="http://code.google.com/appengine/docs/java/javadoc/
 * com/google/appengine/api/memcache/MemcacheService.html#clearAll%28%29">
 * clearAll</a> of <a href="http://code.google.com/appengine/docs/java/javadoc/
 * com/google/appengine/api/memcache/MemcacheService.html">MemcacheService</a>
 * does not respect namespaces - this flushes the cache for every namespace.
 * </p>
 * 
 */
public final class PageCaches {

	/**
	 * Logger.
	 */
	private static final Logger LOGGER = Logger.getLogger(PageCaches.class
			.getName());
	/**
	 * Page cache.
	 * <p>
	 * &lt;requestURI?queryString, page HTML content&gt;
	 * </p>
	 */
	private static final Cache<String, Object> CACHE;
	/**
	 * Maximum count of cacheable pages.
	 */
	private static final int MAX_CACHEABLE_PAGE_CNT = 1024;
	/**
	 * Page cache name.
	 */
	public static final String PAGE_CACHE_NAME = "page";

	/**
	 * Initializes the cache.
	 */
	static {
		CACHE = CacheFactory.getCache(PAGE_CACHE_NAME);
		final RunsOnEnv runsOnEnv = Latkes.getRunsOnEnv();
		if (runsOnEnv.equals(RunsOnEnv.LOCAL)) {
			CACHE.setMaxCount(MAX_CACHEABLE_PAGE_CNT);
			LOGGER.log(Level.INFO, "Initialized page cache[maxCount={0}]",
					MAX_CACHEABLE_PAGE_CNT);
		}
	}

	/**
	 * Gets cache.
	 * 
	 * @return cache
	 */
	public static Cache<String, Object> getCache() {
		return CACHE;
	}

	/**
	 * Gets page content with the specified page key.
	 * 
	 * @param pageKey
	 *            the specified page key
	 * @return page content
	 */
	public static String get(final String pageKey) {
		return (String) CACHE.get(pageKey);
	}

	/**
	 * Puts a page into cache.
	 * 
	 * @param pageKey
	 *            key of the page to put
	 * @param cachedValue
	 *            value to put
	 */
	public static void put(final String pageKey, final JSONObject cachedValue) {
		CACHE.put(pageKey, cachedValue);
	}

	/**
	 * Removes a cached pages specified by the given page key.
	 * 
	 * @param pageKey
	 *            the given page key
	 */
	public static void remove(final String pageKey) {
		CACHE.remove(pageKey);
		Templates.CACHE.clear();
	}

	/**
	 * Removes all cached pages.
	 * 
	 * <p>
	 * <b>Note</b>: This method will flush the cache for every namespace.
	 * </p>
	 */
	public static void removeAll() {
		CACHE.removeAll();
		Templates.CACHE.clear();
	}

	/**
	 * Private default constructor.
	 */
	private PageCaches() {
	}
}
